﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using bzxxxt.admin.entity;
using bzxxxt.dal;
namespace bzxxxt.admin.service
{
    public class MenuService : BaseService
    {
        /// <summary>
        /// 判断指定用户是否具有访问某个页面上的某个操作的权限
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="menucode">菜单模块标识</param>
        /// <param name="action">操作标识</param>
        /// <returns></returns>
        public bool ifAuthorize(int userId, string menucode, string action)
        {
            if (string.IsNullOrEmpty(menucode) || string.IsNullOrEmpty(action)) return false;
            List<string> menus  = null;
            var roleIds = DB.tbUser.Single(m => m.id == userId).tbRole.Select(m => m.id).ToList();
            menus = (from m in DB.tbMenu
                     join r in DB.tbRoleMenuButton on m.id equals r.menuId
                     join b in DB.tbButton on r.buttonId equals b.id
                     where m.parentId > 0 && m.code == menucode && roleIds.Contains(r.roleId)
                     select b.code).Distinct().ToList();
            if (action.Equals("changepwd") || action.Equals("getMyAuthority") ||
                action.Equals("getUserInfo") ||
                action.Equals("getUserMenu") || action.Equals("getbutton"))
            {
                return true;
            }
            if (action.StartsWith("get") || action.StartsWith("search") || action.StartsWith("import")||action.StartsWith("export"))
            {
                //return menus.Contains("browser"); 
                return true;
            }
            return menus.Contains(action);
        }
        public string getMyAuthority(int userId)
        {
            var roleIds = DB.tbUser.Single(m => m.id == userId).tbRole.Select(m=>m.id).ToList();
            List<TreeEntity> menuList = (from m in DB.tbMenu 
                                         where m.parentId == 0 
                                         orderby m.sort
                                         select new TreeEntity
                                         {
                                             id = m.id,
                                             text = m.name,                                             
                                             iconCls = m.icon,
                                             url = m.linkAddress,                                  
                                             parentId = m.parentId,                                                                                       
                                         }).ToList();
            menuList.ForEach(mu =>
            {                
                var children = (from m in DB.tbMenu
                                join r in DB.tbRoleMenuButton on m.id equals r.menuId
                                where m.parentId == mu.id && roleIds.Contains(r.roleId)
                                select new TreeEntity
                                {
                                    id = m.id,
                                    text = m.name,                              
                                    iconCls = m.icon,
                                    url = m.linkAddress,                              
                                    parentId = m.parentId,                              
                                }).Distinct().ToList();                
                if (children != null)
                {
                    mu.children = new List<TreeEntity>();
                    mu.children.AddRange(children);
                    //取子菜单下的按钮
                    children.ForEach(mc =>
                    {
                        var buttons = (from b in DB.tbMenu.FirstOrDefault(m => m.id == mc.id).tbButton
                                       orderby b.sort
                                       select new TreeEntity
                                       {
                                           id = b.id,
                                           text = b.name,
                                           iconCls = b.icon,
                                           parentId = mc.id,
                                       }).ToList();
                        var rmb = DB.tbMenu.FirstOrDefault(m => m.id == mc.id).tbRoleMenuButton.ToList();
                        if (buttons != null)
                        {
                            buttons.ForEach(b =>
                            {
                                if (rmb != null)
                                {
                                    foreach (var bm in rmb)
                                    {
                                        if (roleIds.Contains(bm.roleId) && bm.buttonId == b.id)
                                        {
                                            b.ischecked = true;
                                            break;
                                        }
                                    }
                                }
                            });
                            mc.children = new List<TreeEntity>();
                            mc.children.AddRange(buttons);
                        }
                    });
                }
            });
            string json = JsonUtil.ToJson(menuList.ToList());
            return json;
        }

        public string getMenuByUserId(int userId)
        {
            var roleIds = DB.tbUser.Single(m => m.id == userId).tbRole.Select(m => m.id).ToList();
            List<MenuEntity> menuList = (from m in DB.tbMenu
                                         where m.parentId == 0
                                         orderby m.sort
                                         select new MenuEntity
                                         {
                                             id = m.id,
                                             text = m.name,
                                             sort = m.sort,
                                             iconCls = m.icon,
                                             url = m.linkAddress,
                                             code = m.code,
                                             parentId = m.parentId,
                                             addDate = m.addDate
                                         }).ToList();
            menuList.ForEach(mu =>
            {
                var children = (from m in DB.tbMenu
                                join r in DB.tbRoleMenuButton on m.id equals r.menuId
                                where m.parentId == mu.id && roleIds.Contains(r.roleId)
                                select new MenuEntity
                                {
                                    id = m.id,
                                    text = m.name,
                                    sort = m.sort,
                                    iconCls = m.icon,
                                    url = m.linkAddress,
                                    code = m.code,
                                    parentId = m.parentId,
                                    addDate = m.addDate
                                }).Distinct().OrderBy(m => m.sort).ToList();
                if (children != null)
                {
                    mu.children = new List<MenuEntity>();
                    mu.children.AddRange(children);
                }
            });
            return JsonUtil.ToJson(menuList.ToList());
        }

        public string getMenuByRoleId(int roleId)
        {
            //第一级菜单
            List<TreeEntity> menuList = (from m in DB.tbMenu
                                         where m.parentId == 0
                                         orderby m.sort
                                         select new TreeEntity
                                         {
                                             id = m.id,
                                             text = m.name,
                                             iconCls = m.icon,
                                             parentId = m.parentId
                                         }).ToList();
            //第二级菜单
            menuList.ForEach(mu =>
            {
                var children = (from m in DB.tbMenu
                                where m.parentId == mu.id
                                orderby m.sort
                                select new TreeEntity
                                {
                                    id = m.id,
                                    text = m.name,
                                    iconCls = m.icon,
                                    parentId = m.parentId
                                }).ToList();
                if (children != null)
                {
                    mu.children = new List<TreeEntity>();
                    mu.children.AddRange(children);

                    //取子菜单下的按钮
                    children.ForEach(mc=>{

                        var buttons = (from b in  DB.tbMenu.FirstOrDefault(m => m.id == mc.id).tbButton
                                       orderby b.sort
                                      select new TreeEntity{
                                        id = b.id,
                                        text = b.name,
                                        iconCls = b.icon,
                                        parentId = mc.id,
                                      }).ToList();
                        var rmb = DB.tbMenu.FirstOrDefault(m => m.id == mc.id).tbRoleMenuButton.ToList();
                        if (buttons != null) {
                            buttons.ForEach(b => {
                                if (rmb != null) {
                                    foreach (var bm in rmb) {
                                        if (bm.roleId == roleId && bm.buttonId == b.id)
                                        {
                                            b.ischecked = true;
                                            break;
                                        }
                                    }
                                }
                            });
                            mc.children = new List<TreeEntity>();
                            mc.children.AddRange(buttons);
                        }
                    });
                }
            });

            string json = JsonUtil.ToJson(menuList.ToList());           
            return json;
        }


        public string getall()
        {
            var deplist = (from m in DB.tbMenu
                           where m.parentId == 0
                           orderby m.sort
                           select new MenuEntity
                           {
                               id = m.id,
                               text = m.name,
                               sort = m.sort,
                               iconCls = m.icon,
                               url = m.linkAddress,
                               code = m.code,
                               parentId = m.parentId,
                               buttonIds = m.tbButton.Select(b=>b.id),
                               addDate = m.addDate
                           }).ToList();

            deplist.ForEach(mu =>
            {

                var children = (from m in DB.tbMenu
                                where m.parentId == mu.id
                                orderby m.sort
                                select new MenuEntity
                                {
                                    id = m.id,
                                    text = m.name,
                                    sort = m.sort,
                                    iconCls = m.icon,
                                    url = m.linkAddress,
                                    code = m.code,
                                    parentId = m.parentId,
                                    buttonIds = m.tbButton.Select(b => b.id),
                                    addDate = m.addDate
                                }).ToList();
                if (children != null)
                {
                    mu.children = new List<MenuEntity>();
                    mu.children.AddRange(children);
                }
            });
            string json = JsonUtil.ToJson(deplist.ToList());
            return json;
        }

        public string search(int pageSize, int pageIndex, string order, string where)
        {
            int totalCount = 0;
            where = where + " and parentId=0";
            SqlParameter paramTotalCount = new SqlParameter("@totalCount", totalCount);
            paramTotalCount.Direction = ParameterDirection.Output;
            var pager = DB.tbMenu.SqlQuery("exec sp_Pager @tableName,@columns,@order,@pageSize,@pageIndex,@where,@totalCount output",
                GetPagerParameters("tbMenu", "*", order, where, pageSize, pageIndex, paramTotalCount)).ToList();
            var deplist = (from m in pager
                           select new MenuEntity
                           {
                               id = m.id,
                               text = m.name,
                               sort = m.sort,
                               iconCls = m.icon,
                               url = m.linkAddress,
                               code = m.code,
                               parentId = m.parentId,
                               buttonIds = m.tbButton.Select(b => b.id),
                               addDate = m.addDate
                           }).ToList();

            deplist.ForEach(mu =>
            {
                var children = (from m in DB.tbMenu
                                where m.parentId == mu.id
                                orderby m.sort
                                select new MenuEntity
                                {
                                    id = m.id,
                                    text = m.name,
                                    sort = m.sort,
                                    iconCls = m.icon,
                                    url = m.linkAddress,
                                    code = m.code,
                                    parentId = m.parentId,
                                    buttonIds = m.tbButton.Select(b => b.id),
                                    addDate = m.addDate
                                }).ToList();
                if (children != null)
                {
                    mu.children = new List<MenuEntity>();
                    mu.children.AddRange(children);
                }
            });
            totalCount = Convert.ToInt32(paramTotalCount.Value);
            string json = JsonUtil.ToJson(new { total = totalCount, rows = deplist });
            return json;
        }

        public string add(tbMenu b)
        {
            DB.tbMenu.Add(b);
            DB.SaveChanges();
            string json = JsonUtil.ToJson(new { success = true });
            return json;
        }

        public string edit(tbMenu b)
        {
            var old = DB.tbMenu.FirstOrDefault(m => m.id == b.id);
            old.name = b.name;
            old.parentId = b.parentId;
            old.sort = b.sort;
            old.code = b.code;
            old.icon = b.icon;
            old.linkAddress = b.linkAddress;

            DB.SaveChanges();
            string json = JsonUtil.ToJson(new { success = true });
            return json;
        }

        public string delete(string strIds)
        {
            List<int> ids = new List<int>();
            if (!string.IsNullOrEmpty(strIds))
            {
                string[] arr = strIds.Split(',');
                foreach (var id in arr)
                {
                    ids.Add(int.Parse(id));
                }
            }
            //获取所有的菜单及子菜单Id
            var menuIdList = DB.tbMenu.Where(m => ids.Contains(m.id) || ids.Contains(m.parentId)).Select(m=>m.id).ToList();
           
            menuIdList.ForEach(m => {
                    //删除菜单与按钮之间的关系
                    var menu = DB.tbMenu.SingleOrDefault(mu => mu.id == m);
                    var buttons = menu.tbButton.ToList();
                    buttons.ForEach(b=> menu.tbButton.Remove(b));
                    //删除菜单与角色及按钮之间的关系
                    var menubts = menu.tbRoleMenuButton.ToList();
                    menubts.ForEach(b => menu.tbRoleMenuButton.Remove(b));
                    //删除当前及子菜单
                    DB.tbMenu.Remove(menu);
                });

            DB.SaveChanges();
            return JsonUtil.ToJson(new { success = true });
        }

        public string setbutton(int menuId, string buttonIds)
        {
            var menu = DB.tbMenu.FirstOrDefault(m => m.id == menuId);
            var olds = menu.tbButton.ToList();
            var oldIds = olds.Select(m => m.id).ToList();
            List<int> newIds = new List<int>();
            if (!string.IsNullOrEmpty(buttonIds))
            {
                string[] ids = buttonIds.Split(',');
                foreach (var s in ids)
                {
                    int uid = int.Parse(s);
                    newIds.Add(uid);
                }
            }
            if (olds.Count > 0)
            {
                //计算共有的，保留
                var commIds = oldIds.Intersect(newIds).ToList();
                //从原来的中去除共有的，得到要删除的
                var removeIds = oldIds.Where(m => !commIds.Contains(m)).ToList();
                if (removeIds.Count > 0)
                {
                    olds.ForEach(m => { if (removeIds.Contains(m.id)) menu.tbButton.Remove(m); });
                }
                //从新的去除共有的，得到要添加的
                List<int> nids = new List<int>();
                nids.AddRange(newIds);
                nids.ForEach(m => { if (commIds.Contains(m)) newIds.Remove(m); });
            }
            newIds.ForEach(m =>
            {
                var b = DB.tbButton.FirstOrDefault(mu => mu.id == m);
                menu.tbButton.Add(b);
                
            });

            DB.SaveChanges();

            return JsonUtil.ToJson(new { msg = "分配管理员成功!", success = true });
        }
    }
}